﻿package com.bizmlib.utils
{

	/**
	 * Formats a date to a string using the specified format. Not all the options are implemented.
	 * Currently only supports Y, M, MM, MMM, D, DD, H, HH.
	 *
	 * The following table describes the valid pattern letters:
	 * 
	 * Pattern letter Description 
	 * Y Year. If the number of pattern letters is two, the year is truncated to two digits; otherwise, it appears as four digits. The year can be zero-padded, as the third example shows in the following set of examples: 
	 * 
	 * YY = 05
	 * 
	 * YYYY = 2005
	 * 
	 * YYYYY = 02005 
	 * M Month in year. The format depends on the following criteria: 
	 * If the number of pattern letters is one, the format is interpreted as numeric in one or two digits. 
	 * If the number of pattern letters is two, the format is interpreted as numeric in two digits. 
	 * If the number of pattern letters is three, the format is interpreted as short text. 
	 * If the number of pattern letters is four, the format is interpreted as full text. 
	 * Examples:
	 * 
	 * M = 7
	 * 
	 * MM= 07
	 * 
	 * MMM=Jul
	 * 
	 * MMMM= July 
	 * D Day in month. While a single-letter pattern string for day is valid, you typically use a two-letter pattern string.
	 * 
	 * Examples:
	 * 
	 * D=4
	 * 
	 * DD=04
	 * 
	 * DD=10 
	 * E Day in week. The format depends on the following criteria: 
	 * If the number of pattern letters is one, the format is interpreted as numeric in one or two digits. 
	 * If the number of pattern letters is two, the format is interpreted as numeric in two digits. 
	 * If the number of pattern letters is three, the format is interpreted as short text. 
	 * If the number of pattern letters is four, the format is interpreted as full text. 
	 * Examples:
	 * 
	 * E = 1
	 * 
	 * EE = 01
	 * 
	 * EEE = Mon
	 * 
	 * EEEE = Monday 
	 * A am/pm indicator. 
	 * J Hour in day (0-23). 
	 * H Hour in day (1-24). 
	 * K Hour in am/pm (0-11). 
	 * L Hour in am/pm (1-12). 
	 * N Minute in hour. 
	 * 
	 * Examples:
	 * 
	 * N = 3
	 * 
	 * NN = 03 
	 * S Second in minute. 
	 * 
	 * Examples:
	 * 
	 * SS = 30 
	 * Other text You can add other text into the pattern string to further format the string. You can use punctuation, numbers, and all lowercase letters. You should avoid uppercase letters because they may be interpreted as pattern letters.
	 * 
	 * Example:
	 * 
	 * EEEE, MMM. D, YYYY at H:NN A = Tuesday, Sept. 8, 2005 at 1:26 PM 
	 * 
	 * The default value is "MM/DD/YYYY".
	/**/
	public function formatDateToString(date:Date = null, format:String = "mm/dd/yyyy", monthFullNames:Array = undefined, monthShortNames:Array = undefined):String
	{
		//trace("formatDateToString(" + arguments + ")");
		
		date = date || new Date();
		
		var formattedString:String = format;
		
		var patternY:RegExp = /(y+)/;
		while(formattedString.search(patternY) >= 0)
		{
			formattedString = formattedString.replace(patternY, replaceYFunction);
		}
		
		var patternM:RegExp = /(m+)/;
		while(formattedString.search(patternM) >= 0)
		{
			formattedString = formattedString.replace(patternM, replaceMFunction);
		}
		
		var patternD:RegExp = /(d+)/;
		while(formattedString.search(patternD) >= 0)
		{
			formattedString = formattedString.replace(patternD, replaceDFunction);
		}
		
		var patternH:RegExp = /(h+)/;
		while(formattedString.search(patternH) >= 0)
		{
			formattedString = formattedString.replace(patternH, replaceHFunction);
		}
		
		var patternN:RegExp = /(n+)/;
		while(formattedString.search(patternN) >= 0)
		{
			formattedString = formattedString.replace(patternN, replaceNFunction);
		}
		
		function replaceYFunction():String
		{
			var year:String = String(date.fullYear);
			var originalLength:Number = (String(arguments[0]) || "").length;
			var allowedLength:Number = Math.max(0, Math.min(year.length, originalLength));
			
			return year.substr(Math.max(0, year.length - allowedLength), allowedLength);
		}
		function replaceMFunction():String
		{
			var month:String = String(date.month);
			var pattern:String = String(arguments[0]) || "";
			if(pattern.length<=2)
			{
				month = addCharsToString(month, "0", Math.min(2, pattern.length));
			}
			else if(pattern.length==3)
			{
				if(!monthShortNames)
				{
					monthShortNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
				}
				return monthShortNames[date.month] || "";
			}
			else if(pattern.length==4)
			{
				if(!monthFullNames)
				{
					monthFullNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
				}
				return monthFullNames[date.month] || "";
			}
			
			return month;
		}
		function replaceDFunction():String
		{
			var day:String = String(date.date);
			day = addCharsToString(day, "0", Math.min(2, (String(arguments[0]) || "").length));
			
			return day;
		}
		function replaceHFunction():String
		{
			var hours:String = String(date.hours);
			hours = addCharsToString(hours, "0", Math.min(2, (String(arguments[0]) || "").length));
			
			return hours;
		}
		function replaceNFunction():String
		{
			var minutes:String = String(date.minutes);
			minutes = addCharsToString(minutes, "0", Math.min(2, (String(arguments[0]) || "").length));
			
			return minutes;
		}
		
		return formattedString;
	}
}